﻿using Elasticsearch.Net;
using Infrastructure.ElasticSearch.Configuration;
using Nest;
using System;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Microsoft.Extensions.Hosting;
using Volo.Abp.DependencyInjection;
using System.Collections.Generic;

namespace Infrastructure.ElasticSearch
{
    public class ElasticSearchClientProvider : IElasticSearchClientProvider, ISingletonDependency
    {
        public string HostEnvironmentName { get; }
        private readonly ElasticSearchConfig _searchOptions;
        private Dictionary<string, ElasticClient> clients = new Dictionary<string, ElasticClient>();

        public ElasticSearchClientProvider(ElasticSearchConfig searchOptions, IHostEnvironment hostEnvironment)
        {
            _searchOptions = searchOptions;
            HostEnvironmentName = (string.IsNullOrWhiteSpace(searchOptions.EnvironmentName)
                ? hostEnvironment.EnvironmentName
                : searchOptions.EnvironmentName)?.ToLower() ?? string.Empty;
        }

        public IElasticClient CreateElasticClient(string indexName)
        {
            if (clients.ContainsKey(indexName)) return clients[indexName];
            
            var connectionString = _searchOptions.ConnectionStrings;
            var connectionStrings = connectionString.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
            var nodes = connectionStrings.Select(s => new Uri(s)).ToList();
            var connectionPool = new StaticConnectionPool(nodes);

            var settings = new ConnectionSettings(connectionPool)
                .DefaultIndex(indexName)
                .BasicAuthentication(_searchOptions.UserName, _searchOptions.PassWord);

            if (_searchOptions.IsDebug)
            {
                settings
                    .PrettyJson()
                    .DisableDirectStreaming()
                    .OnRequestCompleted(details =>
                    {
                        if (details.RequestBodyInBytes != null)
                            Debug.WriteLine(Encoding.UTF8.GetString(details.RequestBodyInBytes));
                    });
            }
            var client = new ElasticClient(settings);

            clients.Add(indexName, client);
            return client;
        }

    }
}
